package com.simon.app.october.modules.sys.oauth2;


import com.google.gson.Gson;
import com.simon.app.october.common.utils.Constant;
import com.simon.app.october.common.utils.R;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 自定义shiro的拦截器，让其满足ajax操作，当然我这个设计只满足前后端分离的项目
 * */
public class Oauth2Filter extends AuthenticatingFilter {


    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {

        String token = getRequestToken((HttpServletRequest) request);

        return new Oauth2Token(token);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {

        // 搞不懂作者为什么要这么做，实验下来基本上就是false，感觉有点垃圾
        if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){
            return true;
        }

        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        String token = getRequestToken((HttpServletRequest) request);

        // 如果没有token就直接返回
        if (StringUtils.isBlank(token)) {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;charset=utf-8");
            String json = new Gson().toJson(R.error(401, "无效的token"));
            response.getWriter().print(json);
            return false;
        }

        // 执行登录
        return executeLogin(request, response);
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
                                     ServletRequest request, ServletResponse response) {

        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");

        try {
            // 处理登录失败的异常
            Throwable throwable = e.getCause() == null ? e: e.getCause();

            String json = new Gson().toJson(R.error(401, throwable.getMessage()));
            response.getWriter().print(json);
            return false;
        } catch (IOException e1) {

        }

        return false;
    }

    private String getRequestToken(HttpServletRequest request) {

        // 从header中获取token
        String token = request.getHeader(Constant.TOKEN);

        // 如果header中没有token就在参数中找
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(Constant.TOKEN);
        }

        return token;
    }
}
